package com.qianwei.footpath.manage;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;

import com.common.baselib.string.GsonUtil;
import com.qianwei.footpath.bean.BodyCompositionData;
import com.qianwei.footpath.event.SerialPortEvent;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import tp.xmaihh.serialport.SerialHelper;
import tp.xmaihh.serialport.bean.ComBean;
import tp.xmaihh.serialport.stick.AbsStickPackageHelper;

public class SerialPortManager {
    private static final String TAG = "SerialPortManager";
    private static volatile SerialPortManager instance;

    private static final int MAX_RETRY_COUNT = 3;
    private static final long RETRY_DELAY_MS = 500;
    private static final byte FRAME_HEADER_1 = (byte) 0xA5;
    private static final byte FRAME_HEADER_2 = (byte) 0x5A;
    private static final byte COMPLETION_FLAG = 0x00;

    // 协议相关常量
    private static final int WEIGHT_DATA_ID = 0x0C;
    private static final int WEIGHT_REAL_TIME_DATA_ID = 0x66;
    private static final int HEIGHT_DATA_ID = 0x0D;
    private static final int COMPLETION_DATA_ID = 0x64;
    private static final int ERROR_DATA_ID = 0xC8;
    private static final int ELECTRODE_CONTACT_DATA_ID = 0x41;
    private static final int HAND_CONTACT_DATA_ID = 0x33;
    private static final int HEART_RATE_DATA_ID = 0x40;

    // 错误码映射表
    private static final Map<Integer, String> ERROR_CODE_MAP = new HashMap<Integer, String>() {{
        put(0x1F, "性别参数错误");
        put(0x20, "年龄参数错误");
        put(0x21, "身高参数错误");
        put(0x22, "称重出错，长时间不能稳定读数或标定重量值不对");
        put(0x23, "阻抗测试出错");
        put(0x24, "去皮重失败");
    }};

    private final Context mContext;
    private SerialHelper mSerialHelper;
    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
    private final Queue<Double> weightCache = new ArrayDeque<>(5);
    private final Queue<Double> heightCache = new ArrayDeque<>(5);
    private final Queue<Integer> heartRateCache = new ArrayDeque<>(5);
    private boolean isHand;
    private final Queue<BodyCompositionData> dataCache = new ArrayDeque<>(5);
    private boolean isPeelWeight;

    public void setPeelWeight(boolean peelWeight) {
        isPeelWeight = peelWeight;
    }

    public SerialPortManager(Context context) {
        this.mContext = context.getApplicationContext();
        initSerialHelper();
    }

    public static SerialPortManager getInstance(Context context) {
        if (instance == null) {
            synchronized (SerialPortManager.class) {
                if (instance == null) {
                    instance = new SerialPortManager(context);
                }
            }
        }
        return instance;
    }

    private void notifyWeightData(double value, boolean isRealTime) {
        Log.e(TAG, "notifyWeightData: " + value + "---数据，当前缓存大小:" + weightCache.size());
        if (weightCache.size() >= 3) weightCache.poll();
        weightCache.offer(value);

        mMainHandler.post(() -> {
            EventBus.getDefault().post(
                    isRealTime ?
                            new SerialPortEvent.RealTimeWeightEvent(value) :
                            new SerialPortEvent.WeightDataEvent(value)
            );
        });
    }

    private void notifyHeightData(double value) {
        Log.e(TAG, "notifyHeightData: " + value + "---数据，当前缓存大小:" + heightCache.size());
        if (heightCache.size() >= 3) heightCache.poll();
        heightCache.offer(value);

        mMainHandler.post(() -> {
            EventBus.getDefault().post(new SerialPortEvent.HeightDataEvent(value));
        });
    }

    private void notifyHeartRateData(int value) {
        Log.e(TAG, "notifyHeartRateData: " + value + "---数据，当前缓存大小:" + heartRateCache.size());
        if (heartRateCache.size() >= 3) heartRateCache.poll();
        heartRateCache.offer(value);
        mMainHandler.post(() -> {
            EventBus.getDefault().post(new SerialPortEvent.HeartRateEvent(value));
        });
    }

    private void notifyCompletion() {
        if (isPeelWeight) {
            mMainHandler.post(() -> {
                EventBus.getDefault().post(
                        new SerialPortEvent.PeelWeightCompleteEvent());
            });
        } else {
            mMainHandler.post(() -> {
                if (!weightCache.isEmpty()) {
                    EventBus.getDefault().post(
                            new SerialPortEvent.WeightCompletionEvent(weightCache.peek()));
                    weightCache.clear();
                }

                if (!heightCache.isEmpty()) {
                    EventBus.getDefault().post(
                            new SerialPortEvent.HeightCompletionEvent(heightCache.peek()));
                    heightCache.clear();
                }

                if (!heartRateCache.isEmpty()) {
                    EventBus.getDefault().post(
                            new SerialPortEvent.HeartRateCompletionEvent(heartRateCache.peek()));
                    heartRateCache.clear();
                }
            });
        }
    }

    private void notifyHandData(BodyCompositionData data) {
        mMainHandler.post(() -> {
            if (dataCache.size() >= 3) dataCache.poll();
            dataCache.offer(data);
            EventBus.getDefault().post(new SerialPortEvent.HandCompletionEvent(data));
        });
    }

    private void notifyElectrodeContact(boolean success, int status) {
        mMainHandler.post(() -> {
            EventBus.getDefault().post(
                    new SerialPortEvent.ElectrodeContactEvent(success, status));
        });
    }

    private void notifyError(String message) {
        mMainHandler.post(() -> {
            EventBus.getDefault().post(new SerialPortEvent.ErrorEvent(message));
        });
    }

    private void notifyProtocolError(int errorCode, String errorMsg) {
        mMainHandler.post(() -> {
            EventBus.getDefault().post(
                    new SerialPortEvent.ProtocolErrorEvent(errorCode, errorMsg));
        });
    }


    private void initSerialHelper() {
        mSerialHelper = new SerialHelper("/dev/ttyUSB0", 115200) {
            @Override
            protected void onDataReceived(ComBean comBean) {
                byte[] bRec = comBean.bRec;
                Log.e(TAG, "收到数据: " + bytesToHex(bRec) + "  数据长度：" + comBean.bRec.length);
                if (isHand) {
                    BodyCompositionData handCompositionData = parseFrameList(bRec);
                    if (handCompositionData != null) {
                        Log.e(TAG, "返回双手测体数据: " + GsonUtil.getGson().toJson(handCompositionData));
                        notifyHandData(handCompositionData);
                    }
                } else {
                    parseIncomingData(bRec);
                }

            }
        };
        mSerialHelper.setStickPackageHelper(new AbsStickPackageHelper() {
            @Override
            public byte[] execute(InputStream is) {
                try {
                    int available = is.available();
                    if (available > 0) {
                        byte[] buffer = new byte[available];
                        int size = is.read(buffer);
                        if (size > 0) {
                            return buffer;
                        }
                    } else {
                        SystemClock.sleep(50);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
    }

    public boolean openPort() {
        if (mSerialHelper == null) {
            notifyError("未初始化");
            return false;
        }

        if (mSerialHelper.isOpen()) {
            Log.i(TAG, "串口已打开");
            return true;
        }

        try {
            mSerialHelper.open();
            Log.i(TAG, "串口打开成功");
            return true;
        } catch (IOException e) {
            Log.e(TAG, "串口打开失败: " + e.getMessage());
            notifyError("串口打开失败: " + e.getMessage());
            return false;
        }
    }

    public void closePort() {
        if (mSerialHelper != null && mSerialHelper.isOpen()) {
            mSerialHelper.close();
            Log.i(TAG, "串口已关闭");
        }
    }

    /**
     * 发送实时体重（一次）
     */
    public void sendRealTimeWeightCommand() {
        if (!isPortReady()) return;

        byte[] command = {
                FRAME_HEADER_1, FRAME_HEADER_2,
                0x03, 0x03, 0x45, 0x4B
        };
        isHand = false;
        sendWithRetry(command, MAX_RETRY_COUNT);
    }

    /**
     * 称重
     */
    public void sendWeightCommand() {
        if (!isPortReady()) return;

        byte[] command = {
                FRAME_HEADER_1, FRAME_HEADER_2,
                0x03, 0x03, 0x36, 0x3C
        };
        sendWithRetry(command, MAX_RETRY_COUNT);
    }

    /**
     * 发送身高指令
     */
    public void sendHeightCommand() {
        if (!isPortReady()) return;

        byte[] command = {
                FRAME_HEADER_1, FRAME_HEADER_2,
                0x03, 0x03, 0x35, 0x3B
        };
        sendWithRetry(command, MAX_RETRY_COUNT);
    }

    /**
     * 发送去皮重指令
     */
    public void sendTareCommand() {
        if (!isPortReady()) return;

        // 去皮重指令格式: A5 5A 03 03 34 3A
        byte[] command = {
                FRAME_HEADER_1, FRAME_HEADER_2, // 帧头 0xA5, 0x5A
                0x03,                           // 数据长度(设备ID+功能码)
                0x03,                           // 设备ID
                0x34,                           // 功能码(去皮重)
                0x3A                            // 校验和(0xA5+0x5A+0x03+0x03+0x34 +1 = 0x3A)
        };

        Log.d(TAG, "发送去皮重指令: " + bytesToHex(command));
        sendWithRetry(command, MAX_RETRY_COUNT);
    }

    /**
     * 发送标定体重指令
     *
     * @param weightKg 标定重量值(单位:kg)
     */
    public void sendCalibrateWeightCommand(float weightKg) {
        if (!isPortReady()) return;

        // 标定体重指令格式: A5 5A 05 03 3B [重量高位] [重量低位] [校验和]
        byte[] command = new byte[]{
                FRAME_HEADER_1, FRAME_HEADER_2, // 帧头 0xA5, 0x5A
                0x05,                           // 数据长度(设备ID+功能码+2字节重量)
                0x03,                           // 设备ID
                0x3B                            // 功能码(标定体重)
        };

        // 将kg转换为百克并取整(如61.3kg -> 613百克)
        int weightInHundredGrams = (int) (weightKg * 10);

        // 添加重量值(大端序)
        byte[] weightBytes = new byte[]{
                (byte) ((weightInHundredGrams >> 8) & 0xFF), // 高字节
                (byte) (weightInHundredGrams & 0xFF)         // 低字节
        };

        // 合并数组
        byte[] fullCommand = new byte[command.length + weightBytes.length + 1];
        System.arraycopy(command, 0, fullCommand, 0, command.length);
        System.arraycopy(weightBytes, 0, fullCommand, command.length, weightBytes.length);

        // 计算校验和(所有字节累加后+1)
        int checksum = 0;
        for (byte b : fullCommand) {
            checksum += b & 0xFF;
        }
        fullCommand[fullCommand.length - 1] = (byte) ((checksum + 1) & 0xFF);

        Log.d(TAG, "发送标定体重指令: " + bytesToHex(fullCommand) +
                ", 重量: " + weightKg + "kg");
        sendWithRetry(fullCommand, MAX_RETRY_COUNT);
    }

    /**
     * 标定身高
     *
     * @param heightMm
     */
    public void sendGenerateHeightCalibrationCommand(int heightMm) {
        if (!isPortReady()) return;

        // 协议头固定部分
        byte[] command = new byte[]{
                (byte) 0xA5, (byte) 0x5A,  // 帧头
                0x05,                      // 长度
                0x03,                      // 设备ID
                0x33                       // 功能码（标定身高）
        };

        // 添加身高值（大端序）
        byte[] heightBytes = new byte[]{
                (byte) ((heightMm >> 8) & 0xFF),  // 高字节
                (byte) (heightMm & 0xFF)          // 低字节
        };

        // 合并数组
        byte[] fullCommand = new byte[command.length + heightBytes.length + 1];
        System.arraycopy(command, 0, fullCommand, 0, command.length);
        System.arraycopy(heightBytes, 0, fullCommand, command.length, heightBytes.length);

        // 计算校验和（所有字节累加后+1）
        int checksum = 0;
        for (byte b : fullCommand) {
            checksum += b & 0xFF;
        }
        fullCommand[fullCommand.length - 1] = (byte) ((checksum + 1) & 0xFF);

        sendWithRetry(fullCommand, MAX_RETRY_COUNT);
    }

    /**
     * 电极接触情况查询
     */
    public void sendElectrodeContactCommand() {
        if (!isPortReady()) return;

        byte[] command = {
                FRAME_HEADER_1, FRAME_HEADER_2,
                0x03, 0x03, 0x41, 0x47
        };
        sendWithRetry(command, MAX_RETRY_COUNT);
    }

    public void sendHeartRateCommand() {
        if (!isPortReady()) return;

        byte[] command = {
                FRAME_HEADER_1, FRAME_HEADER_2,
                0x03, 0x03, 0x4B, 0x51
        };
        sendWithRetry(command, MAX_RETRY_COUNT);
    }

    /**
     * 发送双手测体指令
     */
    public void sendHandMeasureCommand(char gender, int age, int height, float weight) {
        if (!isPortReady()) return;

//        gender = 'M';
//        age = 30;
//        height = 1780;
//        weight = 80;
        Log.w(TAG, "发送双手测体指令 " + gender + " " + age + " " + height + " " + weight);
        byte[] frameHeader = {FRAME_HEADER_1, FRAME_HEADER_2};
        byte dataLength = 0x09;
        byte deviceId = 0x01; // 双手测体成分
        byte functionCode = 0x37;
        byte genderByte = (gender == 'M') ? (byte) 0x4D : (byte) 0x57;
        byte ageByte = (byte) age;
        byte[] heightBytes = {(byte) (height >> 8), (byte) (height & 0xFF)};
        int weightInt = (int) (weight * 10); // 转换为百克
        byte[] weightBytes = {(byte) (weightInt >> 8), (byte) (weightInt & 0xFF)};

        byte[] command = new byte[]{frameHeader[0], frameHeader[1], dataLength, deviceId, functionCode, genderByte, ageByte,
                heightBytes[0], heightBytes[1], weightBytes[0], weightBytes[1]};

        byte checksum = (byte) ((calculateChecksum(command) + 1) & 0xFF);
        byte[] fullCommand = new byte[command.length + 1];
        System.arraycopy(command, 0, fullCommand, 0, command.length);
        fullCommand[fullCommand.length - 1] = checksum;

        Log.d(TAG, "发送测体指令: " + bytesToHex(fullCommand));
        isHand = true;
        sendWithRetry(fullCommand, 3);
    }

    private void sendWithRetry(final byte[] data, final int retryCount) {
        new Thread(() -> {
            try {
                mSerialHelper.send(data);
                Log.d(TAG, "发送指令: " + bytesToHex(data));
            } catch (Exception e) {
                if (retryCount > 0) {
                    Log.w(TAG, "指令重试，剩余次数: " + retryCount);
                    try {
                        Thread.sleep(RETRY_DELAY_MS);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                    }
                    sendWithRetry(data, retryCount - 1);
                } else {
                    notifyError("发送失败: " + e.getMessage());
                }
            }
        }).start();
    }

    private void parseIncomingData(byte[] rawData) {
        if (rawData == null || rawData.length < 4) return;

        int dataId = rawData[3] & 0xFF;
        Log.e(TAG, "dataId: " + dataId);
        boolean check = true;

        switch (dataId) {
            case HEART_RATE_DATA_ID:
                check = checkHeartRateData(rawData);
                break;
            case WEIGHT_DATA_ID:
            case WEIGHT_REAL_TIME_DATA_ID:
                check = checkWeightData(rawData);
                break;
            case HEIGHT_DATA_ID:
                check = checkHeightData(rawData);
                break;
            case ELECTRODE_CONTACT_DATA_ID:
                check = checkElectrodeContactData(rawData);
                break;
        }
        if (isPeelWeight && dataId == COMPLETION_DATA_ID) {
            check = checkTareData(rawData);
        }
        if (!check) return;

        // 处理错误码
        if (dataId == ERROR_DATA_ID && rawData.length >= 5) {
            handleProtocolError(rawData[4] & 0xFF);
            return;
        }

        // 根据数据类型分发处理
        switch (dataId) {
            case HEART_RATE_DATA_ID:
                parseHeartRateData(rawData);
                break;
            case WEIGHT_DATA_ID:
                parseWeightData(rawData, false);
                break;
            case WEIGHT_REAL_TIME_DATA_ID:
                parseWeightData(rawData, true);
                break;
            case HEIGHT_DATA_ID:
                parseHeightData(rawData);
                break;
            case COMPLETION_DATA_ID:
                handleCompletion(rawData);
                break;
            case ELECTRODE_CONTACT_DATA_ID:
                handleElectrodeContact(rawData);
                break;
            default:
                Log.w(TAG, "未知数据标识: 0x" + Integer.toHexString(dataId));
        }
    }

    /**
     * 校验去皮重返回数据
     */
    private boolean checkTareData(byte[] rawData) {
        if (rawData.length != 6) {
            Log.e(TAG, "去皮重数据长度错误");
            return false;
        }
        if (rawData[0] != FRAME_HEADER_1 || rawData[1] != FRAME_HEADER_2) {
            Log.e(TAG, "去皮重数据帧头错误");
            return false;
        }
        if (!verifyChecksum(rawData)) {
            Log.e(TAG, "去皮重数据校验和错误");
            return false;
        }
        return true;
    }

    private boolean checkElectrodeContactData(byte[] rawData) {
        if (rawData.length < 5) {
            Log.e(TAG, "电极接触数据长度不足");
            return false;
        }
        if (rawData[0] != FRAME_HEADER_1 || rawData[1] != FRAME_HEADER_2) {
            Log.e(TAG, "电极接触数据帧头错误");
            return false;
        }
        if (!verifyChecksum(rawData)) {
            Log.e(TAG, "电极接触数据校验和错误");
            return false;
        }
        return true;
    }

    private void handleElectrodeContact(byte[] rawData) {
        int status = rawData[4] & 0xFF;
        boolean success = (status == 0xFF || status == 0x33);

        Log.d(TAG, "电极接触状态: 0x" + Integer.toHexString(status)
                + " -> " + (success ? "成功" : "失败"));

        notifyElectrodeContact(success, status);
    }

    private boolean checkWeightData(byte[] rawData) {
        if (rawData.length < 6) return false;
        if (rawData[0] != FRAME_HEADER_1 || rawData[1] != FRAME_HEADER_2) {
            Log.e(TAG, "帧头校验失败");
            return false;
        }
        if (!verifyChecksum(rawData)) {
            Log.e(TAG, "校验和验证失败");
            return false;
        }
        return true;
    }

    private boolean checkHeightData(byte[] rawData) {
        if (rawData == null || rawData.length < 6) {
            Log.e("BCMProtocol", "无效数据长度");
            return false;
        }
        if (rawData[0] != (byte) 0xA5 || rawData[1] != (byte) 0x5A) {
            Log.e("BCMProtocol", "帧头错误");
            return false;
        }
        int dataId = rawData[3] & 0xFF;
        if (dataId != 0x0D) {
            Log.e("BCMProtocol", "非身高数据标识");
            return false;
        }
        return true;
    }

    private boolean checkHeartRateData(byte[] rawData) {
        if (rawData.length < 11) return false; // 根据示例数据长度
        if (!verifyChecksum(rawData)) {
            Log.e(TAG, "心率数据校验失败");
            return false;
        }
        return true;
    }

    private void parseHeartRateData(byte[] rawData) {
        Log.d(TAG, "原始心率数据: " + bytesToHex(rawData));

        if (!verifyChecksum(rawData)) {
            Log.e(TAG, "心率数据校验失败");
            return;
        }

        if (rawData.length < 8) { // 根据协议示例数据长度11（头2 + 长度1 + 数据8）
            Log.e(TAG, "心率数据长度异常");
            return;
        }

        // 解析数据段（示例数据：40 02 A0 03 E8 02 58）
        int heartRate = ((rawData[4] & 0xFF) << 8) | (rawData[5] & 0xFF);
        int param1 = ((rawData[6] & 0xFF) << 8) | (rawData[7] & 0xFF);
        int param2 = ((rawData[8] & 0xFF) << 8) | (rawData[9] & 0xFF);
        int actualHeartRate = (int) (heartRate / 10f); // 转换为 67.2 bpm

        Log.d(TAG, String.format(
                "心率数据: %d bpm, 参数1: %d, 参数2: %d",
                actualHeartRate, param1, param2
        ));

        notifyHeartRateData(actualHeartRate);
    }

    private void parseWeightData(byte[] rawData, boolean isRealTime) {
        double weight = ((rawData[4] & 0xFF) << 8 | (rawData[5] & 0xFF)) * 0.1;
        Log.d(TAG, "解析到体重数据: " + weight + "kg");
        notifyWeightData(weight, isRealTime);
    }

    private void parseHeightData(byte[] rawData) {
        double height = ((rawData[4] & 0xFF) << 8 | (rawData[5] & 0xFF)) / 10.0;
        Log.d(TAG, "解析到身高数据: " + height + "cm");
        notifyHeightData(height);
    }

    private void handleCompletion(byte[] completionData) {
        if (completionData.length < 6) {
            Log.e(TAG, "完成数据长度不足");
            return;
        }
        if (!verifyChecksum(completionData)) {
            Log.e(TAG, "完成数据校验和错误");
            return;
        }
        int completionCode = completionData[4] & 0xFF;
        if (completionCode == COMPLETION_FLAG) {
            notifyCompletion();
        }
    }

    private boolean verifyChecksum(byte[] data) {
        if (data.length < 2) return false;
        int sum = 0;
        for (int i = 0; i < data.length - 1; i++) {
            sum += data[i] & 0xFF;
        }
        return ((sum + 1) & 0xFF) == (data[data.length - 1] & 0xFF);
    }

    private void handleProtocolError(int errorCode) {
        String errorMsg = ERROR_CODE_MAP.getOrDefault(errorCode,
                "未知错误码: 0x" + Integer.toHexString(errorCode));

        Log.e(TAG, "协议错误: " + errorMsg);
        mMainHandler.post(() -> {
            notifyProtocolError(errorCode, errorMsg);
        });
    }

    private int calculateChecksum(byte[] data) {
        int sum = 0;
        for (byte b : data) {
            sum += (b & 0xFF);
        }
        return sum;
    }

    public boolean isPortReady() {
        if (mSerialHelper == null || !mSerialHelper.isOpen()) {
            notifyError("串口未就绪");
            return false;
        }
        return true;
    }

    private String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }

    public void release() {
        closePort();
        weightCache.clear();
        heightCache.clear();
    }

    //-----------------------------------下面是双手测体成分解析-----------------------------------------------------------------

    // 数据标识
    private static final byte DATA_ID_BODY_FAT_RATE = 0x00;      // 体脂肪率
    private static final byte DATA_ID_BODY_WATER_RATE = 0x01;    // 体水分率
    private static final byte DATA_ID_PROTEIN = 0x11;            // 蛋白质
    private static final byte DATA_ID_EXTRACELLULAR_FLUID = 0x0A;// 细胞外液
    private static final byte DATA_ID_INTRACELLULAR_FLUID = 0x0E;// 细胞内液
    private static final byte DATA_ID_MUSCLE_MASS = 0x3C;        // 肌肉量
    private static final byte DATA_ID_BASAL_METABOLISM = 0x05;   // 基础代谢
    private static final byte DATA_ID_FAT_FREE_WEIGHT = 0x09;    // 去脂体重
    private static final byte DATA_ID_BONE_MINERAL = 0x12;       // 无机盐

    // 解析接收到的原始字节数据
    public BodyCompositionData parseFrameList(byte[] rawData) {
        BodyCompositionData result = new BodyCompositionData();
        List<byte[]> frames = splitFrames(rawData);

        for (byte[] frame : frames) {
            if (!isValidFrame(frame)) {
                Log.e(TAG, "Invalid frame: " + bytesToHex(frame));
                continue;
            }

            byte dataId = frame[3];

            // 数据标识位于第3字节
            if (dataId == 0x64) {
                BodyCompositionData data = new BodyCompositionData();
                int completionCode = frame[4] & 0xFF;
                if (completionCode == 0x00) {
                    data = dataCache.peek();
                    Log.e(TAG, "解析结果: " + data);
                    return data;
                }
            } else {
                // 处理数据帧（0x00-0x4A范围内的数据标识）
                if (dataId >= 0x00 && dataId <= 0x4A /*&& frame.length >= 11*/) {
                    parseDataFrame(frame, result);
                } else {
                    Log.e(TAG, "双手体脂未知数据标识: " + dataId + " ---- " + bytesToInt(frame));
                }
                if (dataCache.size() >= 3) {
                    dataCache.poll();
                }
                dataCache.offer(result);
            }
        }


        return null;
    }

    // 解析数据帧
    private void parseDataFrame(byte[] frame, BodyCompositionData result) {
        // 数据段起始位置：帧头2 + 长度1 + 数据标识1 = 4
        byte[] valueBytes = {frame[4], frame[5]};
        int value = bytesToInt(valueBytes);

        switch (frame[3]) { // 数据标识
            case DATA_ID_BODY_FAT_RATE:
                result.setBodyFatRate(value / 10f);
                break;
            case DATA_ID_BODY_WATER_RATE:
                result.setBodyWaterRate(value / 10f);
                break;
            case DATA_ID_PROTEIN:
                result.setProtein(value / 10f);
                break;
            case DATA_ID_EXTRACELLULAR_FLUID:
                result.setExtracellularFluid(value / 10f);
                break;
            case DATA_ID_INTRACELLULAR_FLUID:
                result.setIntracellularFluid(value / 10f);
                break;
            case DATA_ID_MUSCLE_MASS:
                result.setMuscleMass(value / 10f);
                break;
            case DATA_ID_BASAL_METABOLISM:
                result.setBasalMetabolism(value);
                break;
            case DATA_ID_FAT_FREE_WEIGHT:
                result.setFatFreeWeight(value / 10f);
                break;
            case DATA_ID_BONE_MINERAL:
                result.setInorganicSalt(value / 10f);
                break;
        }
    }

    // 检查帧是否有效
    private boolean isValidFrame(byte[] frame) {
        if (frame == null || frame.length < 4) return false; // 最小长度：帧头2 + 长度1 + 数据1

        // 检查帧头
        if (frame[0] != FRAME_HEADER_1 || frame[1] != FRAME_HEADER_2) return false;

        // 数据长度 = 帧总长度 - 帧头(2) - 长度字段(1)
        int declaredLength = frame[2] & 0xFF;
        if (frame.length != declaredLength + 3) return false;

        // 校验和验证（累加到校验和前一个字节）
        byte checksum = handCalculateChecksum(frame);
        return frame[frame.length - 1] == checksum;
    }

    // 计算校验和
    private byte handCalculateChecksum(byte[] frame) {
        int sum = 0;
        for (int i = 0; i < frame.length - 1; i++) {
            sum += frame[i] & 0xFF; // 无符号累加
        }
        return (byte) ((sum + 1) & 0xFF);
    }

    // 从字节流中分割出各个帧
    private List<byte[]> splitFrames(byte[] dataStream) {
        List<byte[]> frames = new ArrayList<>();
        int pos = 0;
        while (pos < dataStream.length - 2) {
            if (dataStream[pos] == FRAME_HEADER_1 && dataStream[pos + 1] == FRAME_HEADER_2) {
                int length = dataStream[pos + 2] & 0xFF;
                if (pos + 3 + length <= dataStream.length) {
                    byte[] frame = new byte[3 + length];
                    System.arraycopy(dataStream, pos, frame, 0, 3 + length);
                    frames.add(frame);
                    pos += 3 + length;
                } else {
                    Log.e(TAG, "数据不完整: " + bytesToHex(dataStream));
                    break; // 数据不完整
                }
            } else {
                pos++; // 继续查找帧头
            }
        }
        return frames;
    }

    // 将2字节转换为有符号整数（高位在前）
    private int bytesToInt(byte[] bytes) {
        if (bytes == null || bytes.length != 2) return 0;
        return ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);
    }
}